﻿using Furion.Logging.Extensions;
using System.Text;

namespace Kyx.Core.Entities;

/// <summary>
/// 数据库审计
/// </summary>
[Table("sys_log_dbaudit")]
[Comment("数据库审计")]
public class SysLogDbAudit : EFCreateEntity
{
    /// <summary>
    /// 实体数据Id
    /// </summary>
    [Comment("实体数据Id")]
    public string EntityId { get; set; }

    /// <summary>
    /// 表名
    /// </summary>
    [Comment("表名")]
    [MaxLength(100)]
    public string TableName { get; set; }

    /// <summary>
    /// 差异
    /// </summary>
    [Comment("差异")]
    public string Diff { get; set; }

    /// <summary>
    /// 执行的语句
    /// </summary>
    [Comment("执行的语句")]
    public string ExecuteSql { get; set; }

    /// <summary>
    /// 操作状态
    /// </summary>
    [Comment("操作状态")]
    public EntityState Operate { get; set; }

    /// <summary>
    /// 创建差异日志
    /// </summary>
    public string GetDiff(Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry entity)
    {
        // 获取实体类型
        var entityType = entity.Entity.GetType();

        // 获取所有实体有效属性，排除 [NotMapper] 属性
        var props = entity.OriginalValues.Properties;

        // 获取实体当前（现在）的值
        var currentValues = entity.CurrentValues;

        // 获取数据库中实体的值
        var databaseValues = entity.GetDatabaseValues();

        StringBuilder propBuilder = new StringBuilder();
        var telantId = string.Empty;

        var ignoreProps = new string[] { nameof(Id), nameof(CreatorUserId), nameof(CreatorUserName), nameof(CreationTime), "UpdateTime", "UpdateUserId", "UpdateUserName", "DeletedUserId", "DeletedUserName", "DeletedTime" };
        // 遍历所有属性
        foreach (var prop in props)
        {
            // 获取属性名
            var propName = prop.Name;

            if (ignoreProps.Contains(propName))
            {
                continue;
            }

            if (!entity.Property(propName).IsModified)
            {
                continue;
            }

            // 获取现在的实体值
            var newValue = currentValues[propName];

            object oldValue = null;
            // 如果是新增数据，则 databaseValues 为空，所以需要判断一下
            if (databaseValues != null)
            {
                oldValue = databaseValues[propName];
            }

            if (prop.Name == "TenantId")
            {
                telantId = oldValue.ToString();
            }

            if (newValue == oldValue || newValue?.ToString() == oldValue?.ToString())
            {
                continue;
            }



            propBuilder.Append($"{propName}：{oldValue} -> {newValue}\r\n");

        }

        if (propBuilder.Length == 0)
        {
            return null;
        }

        TableName = entityType.Name;

        StringBuilder sb = new StringBuilder($"\r\n┏━━━━━━━━━━━ 数据库更新审计日志 ━━━━━━━━━━━\r\n" +
$"表格名称：{entityType.Name}\r\n" +
$"操作人：{CreatorUserId} {CreatorUserName} {CreationTime}\r\n" +
$"操作类型：{entity.State}\r\n" +
$"租户：{telantId}\r\n" +
$"┣ ━━━━━━━━━━━━━━━ 更新字段 ━━━━━━━━━━━━━━━\r\n{propBuilder.ToString()}┗━━━━━━━━━━━ 数据库更新审计日志 ━━━━━━━━━━━\r\n");

        Diff = propBuilder.ToString();

        sb.ToString().LogInformation<SysLogDbAudit>();

        return Diff;

    }
}
